fix: patch 5 medium-severity findings from deep security audit ,Support fractional quantities for crypto spot trading on Delta Exchange ,Fix position book for crypto spot, rmoney FD audit fix and Groww: Optimize master contract and normalize streaming logs#1087
fix: patch 5 medium-severity findings from deep security audit ,Support fractional quantities for crypto spot trading on Delta Exchange ,Fix position book for crypto spot, rmoney FD audit fix and Groww: Optimize master contract and normalize streaming logs#1087marketcalls merged 9 commits intomarketcalls:mainfrom
Conversation
M1: Escape LIKE wildcards in symbol search to prevent broad matching - Add _escape_like() helper for % and _ characters in database/symbol.py M2: Remove traceback disclosure from API error responses - Replace traceback.format_exc() with generic messages in log.py, analyzer.py - Remove unused traceback import from chart_api.py M4: Add input validation for Telegram bot endpoints - rate_limit_per_minute: int, 1-120 range - broadcast message: max 4096 chars - notification priority: int, 1-10 range - stats days: int, 1-365 range M5: Add apikey length constraints (max 256) across all 39 schema fields - schemas.py, data_schemas.py, account_schema.py M6: Restrict ChartSchema payload to prevent storage exhaustion - Max 50 keys, key max 50 chars, value max 1MB in chart_api.py Note: M3 (Windows resource limits) and M7 (Redis rate limiting) are infrastructure-level changes deferred for separate implementation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
3 issues found across 8 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="restx_api/chart_api.py">
<violation number="1" location="restx_api/chart_api.py:86">
P2: The 1MB value-size limit is bypassable because it only validates `str` values; large non-string JSON values are not limited.</violation>
</file>
<file name="restx_api/schemas.py">
<violation number="1" location="restx_api/schemas.py:307">
P3: The custom Length error message is now incorrect: with `max=256` added, overlong API keys will still return "API key is required.".</violation>
</file>
<file name="database/symbol.py">
<violation number="1" location="database/symbol.py:88">
P2: The new wildcard escaping is incomplete: `safe_term` adds backslashes, but `.ilike()` calls do not pass `escape="\\"`, so literal `%`/`_` searches can fail or behave inconsistently across databases.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
- Replace slow df.apply() and iterrows() with vectorized pandas operations - Use bulk_insert_mappings with 10K batch inserts instead of ORM object loop - Master contract download reduced from 5+ minutes to ~22 seconds - Normalize all per-tick WebSocket logging from INFO to DEBUG - Add periodic summary logging (1 info line per 500 ticks) - Remove emojis from log messages and ~150 lines of dead code Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- chart_api: Validate serialized size for all value types, not just strings - symbol.py: Add escape="\\" to all ilike() calls so wildcard escaping works - schemas: Fix incorrect error message on MarginCalculatorSchema apikey field Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 8 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="broker/groww/database/master_contract_db.py">
<violation number="1" location="broker/groww/database/master_contract_db.py:78">
P1: Per-batch `commit()` inside the loop means a mid-way failure leaves the database with partial data. Earlier batches are already committed and cannot be rolled back, yet `delete_symtoken_table()` already wiped the previous data. Move the `commit()` after the loop to keep the entire insert atomic, or wrap the whole operation (delete + insert) in a single transaction.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Use flush() per batch and single commit() after loop so all batches can be rolled back if any fails mid-way. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Crypto spot instruments (BTC_INR, ETH_INR, SOL_INR, XRP_INR) require fractional order sizes (e.g. 0.0001 BTC). Schema quantity fields changed from Int to Float to allow fractional values through API validation. Delta Exchange transform layer uses instrument type lookup to send float for spot and int for derivatives. Also adds spot/move_options to contract type map and uses min_order_size for lotsize. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
5 issues found across 4 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="restx_api/schemas.py">
<violation number="1" location="restx_api/schemas.py:12">
P1: Changing order quantity from integer to float allows fractional quantities that can be rejected downstream by broker order APIs.</violation>
<violation number="2" location="restx_api/schemas.py:148">
P1: Using float for split size/quantity can create fractional child orders and precision errors in split-order generation.</violation>
</file>
<file name="broker/deltaexchange/api/order_api.py">
<violation number="1" location="broker/deltaexchange/api/order_api.py:409">
P1: Using float for smart-order position arithmetic can produce precision drift that gets truncated by downstream `int(qty)` conversion, leading to wrong contract size orders.</violation>
</file>
<file name="broker/deltaexchange/mapping/transform_data.py">
<violation number="1" location="broker/deltaexchange/mapping/transform_data.py:20">
P1: Non-spot quantity conversion silently truncates fractional contracts instead of rejecting invalid sizes.</violation>
</file>
<file name="broker/deltaexchange/database/master_contract_db.py">
<violation number="1" location="broker/deltaexchange/database/master_contract_db.py:463">
P1: `lotsize` is now produced as float but the DB model keeps `lotsize` as `Integer`; fractional spot sizes risk truncation/coercion.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| exchange = data.get("exchange") | ||
| product = data.get("product") | ||
| position_size = int(data.get("position_size", "0")) | ||
| position_size = float(data.get("position_size", "0")) |
There was a problem hiding this comment.
P1: Using float for smart-order position arithmetic can produce precision drift that gets truncated by downstream int(qty) conversion, leading to wrong contract size orders.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At broker/deltaexchange/api/order_api.py, line 409:
<comment>Using float for smart-order position arithmetic can produce precision drift that gets truncated by downstream `int(qty)` conversion, leading to wrong contract size orders.</comment>
<file context>
@@ -406,22 +406,22 @@ def place_smartorder_api(data, auth):
exchange = data.get("exchange")
product = data.get("product")
- position_size = int(data.get("position_size", "0"))
+ position_size = float(data.get("position_size", "0"))
- current_position = int(
</file context>
| # Lot size: use min_order_size from product_specs (important for spot | ||
| # instruments where fractional quantities are allowed, e.g. 0.0001 BTC) | ||
| try: | ||
| lotsize = float(product_specs.get("min_order_size") or 1) |
There was a problem hiding this comment.
P1: lotsize is now produced as float but the DB model keeps lotsize as Integer; fractional spot sizes risk truncation/coercion.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At broker/deltaexchange/database/master_contract_db.py, line 463:
<comment>`lotsize` is now produced as float but the DB model keeps `lotsize` as `Integer`; fractional spot sizes risk truncation/coercion.</comment>
<file context>
@@ -437,16 +439,30 @@ def process_delta_products(products):
+ # Lot size: use min_order_size from product_specs (important for spot
+ # instruments where fractional quantities are allowed, e.g. 0.0001 BTC)
+ try:
+ lotsize = float(product_specs.get("min_order_size") or 1)
+ except (ValueError, TypeError):
+ lotsize = 1.0
</file context>
- Spot positions now fetched from wallet/balances (not in /positions/margined) - float() instead of int() for position size to support fractional spot qty - Reject fractional quantities for derivatives with clear error (not silent truncation) - Revert splitsize to Int (split orders don't need fractional sizes) - Position formatter preserves fractional quantities instead of int() casting Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 5 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="broker/deltaexchange/api/order_api.py">
<violation number="1" location="broker/deltaexchange/api/order_api.py:272">
P2: Fractional spot quantities are added to positions, but downstream close-all logic truncates size to int, causing sub-1 spot positions to be silently skipped.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| positions.append({ | ||
| "product_id": asset.get("asset_id", ""), | ||
| "product_symbol": spot_symbol, | ||
| "size": size, |
There was a problem hiding this comment.
P2: Fractional spot quantities are added to positions, but downstream close-all logic truncates size to int, causing sub-1 spot positions to be silently skipped.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At broker/deltaexchange/api/order_api.py, line 272:
<comment>Fractional spot quantities are added to positions, but downstream close-all logic truncates size to int, causing sub-1 spot positions to be silently skipped.</comment>
<file context>
@@ -228,20 +228,61 @@ def get_trade_book(auth):
+ positions.append({
+ "product_id": asset.get("asset_id", ""),
+ "product_symbol": spot_symbol,
+ "size": size,
+ "entry_price": "0", # Wallet doesn't track entry price
+ "realized_pnl": "0",
</file context>
…ulation int() in margin_data.py silently truncated sub-1 spot quantities (e.g. 0.0001 BTC) to 0, causing them to be skipped. Use _order_size() to preserve fractional spot sizes while keeping integer enforcement for derivatives. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add requests.Session for HTTP connection pooling instead of bare requests calls - Close all HTTP responses explicitly via try/finally to prevent FD leaks - Add close() method for full teardown of Socket.IO client + HTTP session - Force-kill Engine.IO transport on disconnect/reconnect to release FDs and threads - Use threading.Event for interruptible reconnect sleep so disconnect() returns instantly - Close previous ws_client on re-initialize to prevent orphaned resources Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix: patch 5 medium-severity findings from deep security audit
Summary by cubic
Fixes five medium-severity security issues. Adds fractional spot trading and spot positions for Delta Exchange, improves Groww master contract import and logs, and resolves RMoney WebSocket file‑descriptor leaks.
Bug Fixes
%and_in symbol search (withescape="\\")to prevent broad matches.apikeyto 1–256 chars across schemas; fix MarginCalculatorSchema message.product_specs.min_order_size, mapspot/move_options, preferstrike_price; reject fractional qty for derivatives; fix margin calc truncation via_order_size().requests.Session, explicit response closes, full client teardown, interruptible reconnect, and closing prior client on re-init.Performance
bulk_insert_mappingswith per-batchflush()and singlecommit()for atomic rollback; cut import from 5+ minutes to ~22 seconds.Written for commit 75cf1c1. Summary will update on new commits.